package com.google.jguery.server;

import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.regex.Pattern;

public class InvertedIndex {
    String input;
    Map<String, ArrayList<Integer>> wordsIndex = new HashMap<String, ArrayList<Integer>>();

    public InvertedIndex() {
    }

    public InvertedIndex(String input) {
        this.input = input;
        buildIndex();
    }

    static Pattern whitespace = Pattern.compile("\\s+");
    static Pattern sentencePunctuation = Pattern.compile("[.,;]$");

    public void buildIndex() {
        String [] words = whitespace.split(input);
        int length = words.length;
        for (int i=0; i<length; i++) {
            String word = words[i].toLowerCase();
            ArrayList<Integer> list = wordsIndex.get(word);
            if (list == null) {
                list = new ArrayList<Integer>();
                wordsIndex.put(word, list);
            }
            list.add(i);
            if (sentencePunctuation.matcher(word).find()) {
                word = sentencePunctuation.matcher(word).replaceFirst("");
                ArrayList<Integer> list2 = wordsIndex.get(word);
                if (list2 == null) {
                    list2 = new ArrayList<Integer>();
                    wordsIndex.put(word, list2);
                }
                list2.add(i);
            }
            if (word.indexOf('/') != -1) {
                String [] splitWords = word.split("/");
                for (String w : splitWords) {
                    ArrayList<Integer> list2 = wordsIndex.get(w);
                    if (list2 == null) {
                        list2 = new ArrayList<Integer>();
                        wordsIndex.put(w, list2);
                    }
                    list2.add(i);
                }
            }
        }
    }
    
    public boolean contains(String hay) {
        String [] hays = whitespace.split(hay);
        int length = hays.length;
        if (length == 1) {
            return wordsIndex.containsKey(hays[0]);
        } else {
            boolean result = false;
            ArrayList<ArrayList<Integer>> positionsList = new ArrayList<ArrayList<Integer>>();
            for (int i=0; i<length; i++) {
                ArrayList<Integer> list = wordsIndex.get(hays[i]);
                if (list == null) return false;
                positionsList.add(list);
            }
            result = findConsecutiveNum(positionsList);
            return result;
        }
    }
    
    public boolean findConsecutiveNum(ArrayList<ArrayList<Integer>> positionsList) {
        boolean result = true;
        int start = 0;
        int length = positionsList.size();
        int minCount = 1000;
        for (int i=0; i<length; i++) {
            if (positionsList.get(i).size()<minCount) {
                minCount = positionsList.get(i).size();
                start = i;
            }
        }
        for (int i=0; i<minCount; i++) {
            result = true;
            int test = positionsList.get(start).get(i);
            int initTest = test;
            int initStart = start;
            //I could again test which direction is smaller and test, but should be good for now
            while(start>0) {
                test--;
                start--;
                if (!positionsList.get(start).contains(test)) {
                    result = false;
                    break;
                }
            }
            if (!result) break;
            test = initTest;
            start = initStart;
            while(start<length-1){
                test++;
                start++;
                if (!positionsList.get(start).contains(test)) {
                    result = false;
                    break;
                }
            }
            if (result) {
                return result;
            }
        }
        return result;
    }

    
    
    
}
